package net.plentz.tagger.data.access;

import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.util.Iterator;

import net.plentz.tagger.data.ArtworkData;
import net.plentz.tagger.data.FieldData;
import net.plentz.tagger.data.MusicData;
import net.plentz.tagger.data.MusicData.Field;

import org.eclipse.swt.graphics.ImageData;

import entagged.audioformats.AudioFile;
import entagged.audioformats.AudioFileIO;
import entagged.audioformats.Tag;
import entagged.audioformats.exceptions.CannotReadException;
import entagged.audioformats.generic.TagField;
import entagged.audioformats.mp3.Id3v1Tag;
import entagged.audioformats.mp3.Id3v2Tag;
import entagged.audioformats.mp3.util.id3frames.ApicId3Frame;

public class MusicDAO {

	public static MusicData getMusicData(File file) throws CannotReadException, IOException {

		AudioFile audioFile = AudioFileIO.read(file);
		Tag tag = audioFile.getTag();
		MusicData musicData = new MusicData();

		musicData.setFilename(file.getAbsolutePath());
		musicData.setSamplingRate(audioFile.getSamplingRate());
		musicData.setLength(audioFile.getPreciseLength());

		int id3MajorVersion = -1;

		if (tag instanceof Id3v1Tag) {
			// ID3v1 Tag
			id3MajorVersion = 1;
		} else if (tag instanceof Id3v2Tag) {
			// ID3v2 Tag
			id3MajorVersion = 2;
		}

		Iterator<TagField> fieldIterator = tag.getFields();
		while (fieldIterator.hasNext()) {
			TagField tagField = fieldIterator.next();
			switch (id3MajorVersion) {
				case 1: {
					Field field = Field.valueOf(tagField.getId());
					musicData.setFieldValue(field, tagField.toString().substring(tagField.toString().indexOf(":") + 2));
					break;
				}
				case 2: {
					if (tagField.getId().equals("APIC")) {
						// It's an album cover
						ApicId3Frame apicFrame = (ApicId3Frame)tagField;
						BufferedInputStream in = null;
						try {
							in = new BufferedInputStream(new ByteArrayInputStream(apicFrame.getData()));
							ImageData imageData = new ImageData(in);
							ArtworkData artworkData = new ArtworkData(imageData);
							musicData.setArtworkData(artworkData);
						} finally {
							if (in != null) {
								in.close();
							}
						}
					} else {
						Field field = MusicData.Id3v2FieldMap.get(FieldData.Id3v2Field.valueOf(tagField.getId()));
						musicData.setFieldValue(field, tagField.toString());
					}
					break;
				}
			}
		}

		return musicData;

	}
}
